
package fr.mehfile.api.update.tasks;

import fr.mehfile.api.database.DataBase;
import fr.mehfile.api.database.NewsFromDatabase;
import fr.mehfile.api.update.Tasks;
import fr.mehfile.api.update.TasksListener;
import fr.mehfile.view.utils.Utils;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Environment;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;

public class DownloadImagesTask extends Tasks {
    private final static String TAG = "DownloadImagesTask";

    private Context context;
    private DataBase database;

    public DownloadImagesTask(Context context, TasksListener listener, DataBase database) {
        super(Tasks.DOWNLOAD_IMAGE_TASK_ID, listener);

        this.context = context;
        this.database = database;
    }

    @Override
    protected Object doInBackground(Object... params) {
        HttpParams my_httpParams = new BasicHttpParams();
        DefaultHttpClient httpClient = new DefaultHttpClient(my_httpParams);

        Object returnValue = null;
        ArrayList<NewsFromDatabase> newsFromDatabase = database.getAllNews();
        for (int i = 0; i < newsFromDatabase.size(); i++) {
        
            NewsFromDatabase currentNewsFromDatabase = newsFromDatabase.get(i);
            try {
                launchDownload(httpClient, currentNewsFromDatabase);
            } catch (Exception e) {
                returnValue = e;
            }
        }

        return returnValue;
    }

    @Override
    protected void onPostExecute(Object result) {
        super.onPostExecute(result);

        if (result instanceof Exception) {
            getListener().onError(this, (Exception) result);
        } else {
            getListener().onComplete(this, result);
        }

    }

    private void launchDownload(DefaultHttpClient httpClient,
            NewsFromDatabase currentNewsFromDatabase)
            throws Exception {

        URI uri = currentNewsFromDatabase.getImageUrl().toURI();
        Utils.debugger.logDebug(TAG, "--------- " + currentNewsFromDatabase.getTitle() + " ------");
        Utils.debugger.logDebug(TAG, "need downloading image ? ");
        if (currentNewsFromDatabase.imageNeedToDownload(context)) {
            Utils.debugger.logDebug(TAG, "yes");
            Uri destUri = downloadFile(context, httpClient, uri, currentNewsFromDatabase.getFileName());
            currentNewsFromDatabase.setImageLocation(destUri.toString());
            database.updateNews(currentNewsFromDatabase);
        }

        Utils.debugger.logDebug(TAG, "---------------------------");
    }

    public Uri downloadFile(Context context, DefaultHttpClient httpClient, URI imageURL,
            String fileName) throws IOException {
        Uri uri = null;
        FileOutputStream out = null;
        File destTempfile = null;
        try {
            Utils.debugger.logDebug(TAG, "Start downloading image #" + fileName);
            File dir = null;
            if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
                dir = new File(Environment.getExternalStorageDirectory(),
                        NewsFromDatabase.imagesDirectoryOnSdCard);
                if (!dir.exists()) {
                    dir.mkdirs();

                }

            } else {
                dir = context.getDir(NewsFromDatabase.imagesDirectoryOnApplication,
                        Context.MODE_WORLD_READABLE
                                | Context.MODE_WORLD_WRITEABLE);
            }
            destTempfile = new File(dir, fileName + ".temp");

            HttpGet get = new HttpGet(imageURL);

            HttpResponse response = httpClient.execute(get);

            if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK)
                throw new IOException();

            out = new FileOutputStream(destTempfile);
            HttpEntity entity = response.getEntity();

            if (entity != null) {
                try {
                    entity.writeTo(out);
                } catch (IOException e) {
                    e.printStackTrace();
                    if (out != null)
                        out.close();
                    out = null;

                    throw new IOException();
                }
            }

            out.close();
            out = null;

            if (Drawable.createFromPath(destTempfile.getAbsolutePath()) == null) {
                Utils.debugger.logDebug(TAG, "Downloading failed image #" + fileName
                        + " cannot create drawable from path " + destTempfile.getAbsolutePath());
                throw new IOException();
            }

            File destfile = new File(dir, "" + fileName);
            boolean succeed = destTempfile.renameTo(destfile);

            if (!succeed) {
                Utils.debugger.logDebug(TAG, "Error downloading image #" + fileName +
                        " cannot rename from " + destTempfile.getAbsolutePath() +
                        " to " + destfile.getCanonicalPath());
                throw new IOException();
            }

            uri = Uri.fromFile(destfile);

        } catch (IOException e) {
            e.printStackTrace();
            Utils.debugger.logDebug(TAG, "Downloading failed image #" + fileName);
            if (destTempfile != null)
                destTempfile.delete();
            throw new IOException();
        } catch (SecurityException e) {
            Utils.debugger.logDebug(TAG, "Downloading failed image #" + fileName);
            if (destTempfile != null)
                destTempfile.delete();
            throw new IOException();
        }

        Utils.debugger.logDebug(TAG,
                "Finish downloading image #" + fileName + " to " + uri.toString());

        return uri;

    }

}
